package com.whmskj.xjlhbc.mobile.schedule;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.whmskj.xjlhbc.db.DataSourceType;
import com.whmskj.xjlhbc.db.DynamicDataSourceContextHolder;
import com.whmskj.xjlhbc.domain.*;
import com.whmskj.xjlhbc.mapper.*;
import com.whmskj.xjlhbc.mobile.GetStartDate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@Component
public class MesElectricitTask {

    @Autowired
    private ScdbMapper scdbMapper;

    @Autowired
    private MesdbMapper mesdbMapper;

    @Autowired
    private MesdbHistoryMapper mesdbHistoryMapper;

    @Autowired
    private MesdbRealMapper mesdbRealMapper;

    @Autowired
    private MesdbClassMapper mesdbClassMapper;

    @Autowired
    private MesdbDayMapper mesdbDayMapper;

    @Autowired
    private ScktMapper scktMapper;

    @Autowired
    private MesktMapper mesktMapper;

    @Autowired
    private MesktHistoryMapper mesktHistoryMapper;

    @Autowired
    private Bcxt06DistributionRoomElectricitMapper bcxt06DistributionRoomElectricitMapper;

    private List<Bcxt06DistributionRoomElectricit> electricits = new ArrayList<>();

    @PostConstruct
    public void getElectricits(){
        electricits = bcxt06DistributionRoomElectricitMapper.selectList(null);
    }


    /**
     * 电表实时数据,电表实时监测数据
     * 一分钟更新
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void save1(){
        try{
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SC.name());
            List<Scdb> list = scdbMapper.select();
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
            list.forEach(item -> {
                LambdaQueryWrapper<Mesdb> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Mesdb::getMacid, item.getDevice())
                        .eq(BaseEntity::getMacname,item.getDbname())
                        .last("limit 1");
                Bcxt06DistributionRoomElectricit electricit = getElectricit(item.getDevice(), item.getDbname());
                Mesdb entity = Optional.ofNullable(mesdbMapper.selectOne(queryWrapper)).orElseGet(Mesdb::new);
                Long id = entity.getId();
                BeanUtils.copyProperties(item, entity);
                entity.setId(id);
                entity.setMacid(item.getDevice());
                entity.setMacname(item.getDbname());
                entity.setPdsname(electricit.getPowerDisRoom());
                entity.setDbname(electricit.getFormName());
                entity.setStatus(null);
                entity.setWorkshop(electricit.getWorkshop());
                int result = Objects.isNull(id) ? mesdbMapper.insert(entity) : mesdbMapper.updateById(entity);

                LambdaQueryWrapper<MesdbReal> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(MesdbReal::getMacid, item.getDevice())
                        .eq(BaseEntity::getMacname,item.getDbname())
                        .last("limit 1");
                MesdbReal mesdbReal = Optional.ofNullable(mesdbRealMapper.selectOne(queryWrapper1)).orElseGet(MesdbReal::new);
                id = mesdbReal.getId();
                mesdbReal.setId(id);
                mesdbReal.setMacid(item.getDevice());
                mesdbReal.setMacname(item.getDbname());
                mesdbReal.setPdsname(electricit.getPowerDisRoom());
                mesdbReal.setDbname(electricit.getFormName());
                mesdbReal.setStatus(null);
                mesdbReal.setTs(entity.getTs());
                mesdbReal.setWorkshop(electricit.getWorkshop());
                mesdbReal.setA720(entity.getA720());
                mesdbReal.setClasses(getBnh(entity));
                mesdbReal.setDay(getDay(entity));
                mesdbReal.setMonth(getMonth(entity));
                result = Objects.isNull(id) ? mesdbRealMapper.insert(mesdbReal) : mesdbRealMapper.updateById(mesdbReal);

            });
        }finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    /**
     * 电表班次用电统计
     */
    @Scheduled(cron = "0 0 9,15,21 * * ?")
    public void save2(){
        try{
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SC.name());
            List<Scdb> list = scdbMapper.select();
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
            list.forEach(item -> {
                Bcxt06DistributionRoomElectricit electricit = getElectricit(item.getDevice(), item.getDbname());
                String startDate = GetStartDate.getClassStartDate();
                String dateymd = startDate.substring(0, 10);
                LambdaQueryWrapper<MesdbClass> queryWrapper2 = new LambdaQueryWrapper<>();
                queryWrapper2.eq(MesdbClass::getMacid, item.getDevice())
                        .eq(BaseEntity::getMacname,item.getDbname())
                        .eq(MesdbClass::getStartdatetime,startDate)
                        .last("limit 1");
                Mesdb db = new Mesdb();
                db.setA720(item.getA720());
                db.setMacid(item.getDevice());
                db.setMacname(item.getDbname());
                MesdbClass mesdbClass = Optional.ofNullable(mesdbClassMapper.selectOne(queryWrapper2)).orElseGet(MesdbClass::new);
                Long id = mesdbClass.getId();
                mesdbClass.setId(id);
                mesdbClass.setMacid(item.getDevice());
                mesdbClass.setMacname(item.getDbname());
                mesdbClass.setPdsname(electricit.getPowerDisRoom());
                mesdbClass.setDbname(electricit.getFormName());
                mesdbClass.setStatus(null);
                mesdbClass.setTs(item.getTs());
                mesdbClass.setWorkshop(electricit.getWorkshop());
                mesdbClass.setA720(item.getA720());
                mesdbClass.setClasses(getBnh(db));
                mesdbClass.setStartdatetime(startDate);
                mesdbClass.setDateymd(dateymd);
                int result = Objects.isNull(id) ? mesdbClassMapper.insert(mesdbClass) : mesdbClassMapper.updateById(mesdbClass);
            });
        }finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    /**
     * 电表日用电统计
     */
    @Scheduled(cron = "0 0 9 * * ?")
    public void save3(){
        try{
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SC.name());
            List<Scdb> list = scdbMapper.select();
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
            list.forEach(item -> {
                Bcxt06DistributionRoomElectricit electricit = getElectricit(item.getDevice(), item.getDbname());
                String dateymd = GetStartDate.getYesterdayStartDate().substring(0, 10);
                LambdaQueryWrapper<MesdbDay> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(MesdbDay::getMacid, item.getDevice())
                        .eq(BaseEntity::getMacname,item.getDbname())
                        .eq(MesdbDay::getDateymd,dateymd)
                        .last("limit 1");

                Mesdb db = new Mesdb();
                db.setA720(item.getA720());
                db.setMacid(item.getDevice());
                db.setMacname(item.getDbname());
                MesdbDay mesdbDay = Optional.ofNullable(mesdbDayMapper.selectOne(wrapper)).orElseGet(MesdbDay::new);
                Long id = mesdbDay.getId();
                mesdbDay.setId(id);
                mesdbDay.setMacid(item.getDevice());
                mesdbDay.setMacname(item.getDbname());
                mesdbDay.setPdsname(electricit.getPowerDisRoom());
                mesdbDay.setDbname(electricit.getFormName());
                mesdbDay.setStatus(null);
                mesdbDay.setTs(item.getTs());
                mesdbDay.setWorkshop(electricit.getWorkshop());
                mesdbDay.setA720(item.getA720());
                mesdbDay.setDay(getYesterday(db));
                mesdbDay.setDateymd(dateymd);
                int result = Objects.isNull(id) ? mesdbDayMapper.insert(mesdbDay) : mesdbDayMapper.updateById(mesdbDay);
            });
        }finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    private String getNh(Mesdb db,String startDate){
        LambdaQueryWrapper<MesdbHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.ge(BaseEntity::getTs, startDate)
                .eq(MesdbBaseEntity::getMacid, db.getMacid())
                .eq(BaseEntity::getMacname, db.getMacname())
                .orderByAsc(BaseEntity::getTs).last("limit 1");
        MesdbHistory mesdbHistory = Optional.ofNullable(mesdbHistoryMapper.selectOne(wrapper)).orElseGet(MesdbHistory::new);
        double start = Optional.ofNullable(mesdbHistory.getA720()).orElse(db.getA720());
        double end = db.getA720();
        return String.format("%.2f",Math.max(end - start, 0));
    }

    //实时检测班能耗
    private String getBnh(Mesdb db){
        String startDate = GetStartDate.getClassStartDate();
        return getNh(db, startDate);
    }

    private String getDay(Mesdb db){
        String startDate = GetStartDate.getDayStartDate();
        return getNh(db, startDate);
    }

    private String getYesterday(Mesdb db){
        String startDate = GetStartDate.getYesterdayStartDate();
        return getNh(db, startDate);
    }

    private String getMonth(Mesdb db){
        String startDate = GetStartDate.getMonthStartDate();
        return getNh(db, startDate);
    }


    /**
     * 每小时执行一次,电表历史记录
     * 空调历史记录
     */
    @Scheduled(cron = "0 0 * * * ?")
    public void save2History(){
        try{
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SC.name());
            List<Scdb> scdbList = scdbMapper.select();
            List<Sckt> queryList = scktMapper.select();

            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
            scdbList.forEach(item -> {
                Bcxt06DistributionRoomElectricit electricit = getElectricit(item.getDevice(), item.getDbname());
                MesdbHistory entity = new MesdbHistory();
                BeanUtils.copyProperties(item, entity);
                entity.setId(null);
                entity.setMacid(item.getDevice());
                entity.setMacname(item.getDbname());
                entity.setPdsname(electricit.getPowerDisRoom());
                entity.setDbname(electricit.getFormName());
                entity.setStatus(null);
                entity.setWorkshop(electricit.getWorkshop());
                int result = mesdbHistoryMapper.insert(entity);
            });

            queryList.forEach(item->{
                String xTagName = item.getXTagName();
                item.setXTagName(xTagName.substring(xTagName.lastIndexOf(".")+1));
            });
            String wd = "温度";
            String sd = "湿度";
            String wdset = "温度设定值";
            String sdset = "湿度设定值";
            for(int i = 1;i <= 5;i++) {
                String tagName = i != 5 ? i+"布厂车间" : "整经车间";
                List<Sckt> list = queryList.stream().filter(f -> f.getXTagName().startsWith(tagName)).collect(Collectors.toList());
                Sckt sckt = list.stream().filter(f -> f.getXTagName().endsWith(wd)).findFirst().orElse(new Sckt());
                Sckt sckt1 = list.stream().filter(f -> f.getXTagName().endsWith(sd)).findFirst().orElse(new Sckt());
                Sckt sckt2 = list.stream().filter(f -> f.getXTagName().endsWith(wdset)).findFirst().orElse(new Sckt());
                Sckt sckt3 = list.stream().filter(f -> f.getXTagName().endsWith(sdset)).findFirst().orElse(new Sckt());

                LambdaQueryWrapper<Meskt> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Meskt::getMacid, i).last("limit 1");
                MesktHistory entity = new MesktHistory();
                entity.setMacid(String.valueOf(i));
                entity.setWd(sckt.getXValue());
                entity.setMacname(i != 5 ? "AC"+i+"空调" : "整经空调");
                entity.setTs(sckt.getXTimeStamp());
                entity.setSd(sckt1.getXValue());
                entity.setWdset(sckt2.getXValue());
                entity.setSdset(sckt3.getXValue());
                int result = mesktHistoryMapper.insert(entity);
            }
        }finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    /**
     * 空调
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void save4(){
        try{
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SC.name());
            List<Sckt> queryList = scktMapper.select();
            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
            queryList.forEach(item->{
                String xTagName = item.getXTagName();
                item.setXTagName(xTagName.substring(xTagName.lastIndexOf(".")+1));
            });
            String wd = "温度";
            String sd = "湿度";
            String wdset = "温度设定值";
            String sdset = "湿度设定值";
            for(int i = 1;i <= 5;i++) {
                String tagName = i != 5 ? i+"布厂车间" : "整经车间";
                List<Sckt> list = queryList.stream().filter(f -> f.getXTagName().startsWith(tagName)).collect(Collectors.toList());
                Sckt sckt = list.stream().filter(f -> f.getXTagName().endsWith(wd)).findFirst().orElse(new Sckt());
                Sckt sckt1 = list.stream().filter(f -> f.getXTagName().endsWith(sd)).findFirst().orElse(new Sckt());
                Sckt sckt2 = list.stream().filter(f -> f.getXTagName().endsWith(wdset)).findFirst().orElse(new Sckt());
                Sckt sckt3 = list.stream().filter(f -> f.getXTagName().endsWith(sdset)).findFirst().orElse(new Sckt());

                LambdaQueryWrapper<Meskt> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Meskt::getMacid, i).last("limit 1");
                Meskt entity = Optional.ofNullable(mesktMapper.selectOne(queryWrapper)).orElseGet(Meskt::new);
                Long id = entity.getId();
                entity.setMacid(String.valueOf(i));
                entity.setWd(sckt.getXValue());
                entity.setMacname(i != 5 ? "AC"+i+"空调" : "整经空调");
                entity.setTs(sckt.getXTimeStamp());
                entity.setSd(sckt1.getXValue());
                entity.setWdset(sckt2.getXValue());
                entity.setSdset(sckt3.getXValue());
                int result = Objects.isNull(id) ? mesktMapper.insert(entity) : mesktMapper.updateById(entity);
            }
        }finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    private Bcxt06DistributionRoomElectricit getElectricit(String formNumber,String powerDisNumber){
        return electricits.stream().filter(f -> f.getFormNumber().equals(formNumber) &&
                f.getPowerDisNumber().equals(powerDisNumber)).findFirst().orElseGet(Bcxt06DistributionRoomElectricit::new);
    }

}
